home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume12 / pathalias9 / part01 next >
Encoding:
Internet Message Format  |  1987-10-08  |  56.7 KB

  1. Subject:  v12i001:  Pathalias, version 9, Part01/02
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: honey@CITI.UMICH.EDU (Peter Honeyman)
  7. Posting-number: Volume 12, Issue 1
  8. Archive-name: pathalias9/part01
  9.  
  10. [  This is the latest and greatest pathalias, and other tools.  It may
  11.    well be the last one peter ever works on, judging from his off-line
  12.    remarks... :-)  This version has had several bugs fixed, and has
  13.    been tested on BSD, Sun, 3B, SysV, Mac, etc.  MOST IMPORTANTLY:
  14.    it has several new features, and additions to the input syntax, that
  15.    you will need for all future UUCP maps.  Finally, had I an
  16.    irrelevant axe to grind, I'd point out that this code has no
  17.    copyright and is in the public domain.  --r$  ]
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 1 (of 2)."
  26. # Contents:  CHANGES MANIFEST Makefile README addlink.c arpa-privates
  27. #   config.h def.h local.c main.c make.honey makedb.c mapaux.c mem.c
  28. #   printit.c
  29. # Wrapped by rsalz@uunet on Mon Oct  5 22:45:08 1987
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f CHANGES -a "${1}" != "-c" ; then 
  32.   echo shar: Will not over-write existing file \"CHANGES\"
  33. else
  34. echo shar: Extracting \"CHANGES\" \(941 characters\)
  35. sed "s/^X//" >CHANGES <<'END_OF_CHANGES'
  36. X-- mod.sources, 10/87 -- version 9
  37. XTerminal edges and domains (<host> syntax and -D option).
  38. XDead hosts and edges in the input stream.
  39. XEmpty private list ends scope of privates.
  40. XFirst hop cost in output (-f option).
  41. XPenalize deprecated hosts (-a option).
  42. X
  43. X-- mod.sources, 4.3bsd, 1/86 -- version 8
  44. XImproved alias treatment.
  45. XRoutes to domain gateways.
  46. XLeading dot in name implies domain.
  47. XLink/host tracing (-t option).
  48. XUse getopt().
  49. X
  50. X-- mod.sources, 8/85 -- version 7
  51. XPrivate hosts documented.
  52. XHomegrown scanner -- it was true what they said about lex.
  53. XMakedb.
  54. XDomains and gateways.
  55. XDEAD back link.
  56. X
  57. X-- net.sources, 1/85 -- version 6
  58. XNo ! in dbm key.
  59. XNetwork character must be one of !@%: -- dot is dead.
  60. XPrivate hosts.
  61. XDiscourage hybrid addresses.  
  62. XMagic @ <-> % rule.
  63. X
  64. X-- 1983-1984 -- version 5
  65. XReverse sense of the -c (cost) flag.
  66. XUse cheapest among duplicate links.
  67. XElide network names in output.
  68. X
  69. X-- epoch (smb version) -- versions 1-4
  70. END_OF_CHANGES
  71. if test 941 -ne `wc -c <CHANGES`; then
  72.     echo shar: \"CHANGES\" unpacked with wrong size!
  73. fi
  74. # end of overwriting check
  75. fi
  76. if test -f MANIFEST -a "${1}" != "-c" ; then 
  77.   echo shar: Will not over-write existing file \"MANIFEST\"
  78. else
  79. echo shar: Extracting \"MANIFEST\" \(714 characters\)
  80. sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
  81. X   File Name        Archive #    Description
  82. X-----------------------------------------------------------
  83. X CHANGES                   1    
  84. X MANIFEST                  1    This shipping list
  85. X Makefile                  1    
  86. X README                    1    
  87. X addlink.c                 1    
  88. X addnode.c                 2    
  89. X arpa-privates             1    
  90. X arpatxt.c                 2    
  91. X config.h                  1    
  92. X def.h                     1    
  93. X local.c                   1    
  94. X main.c                    1    
  95. X make.honey                1    
  96. X makedb.c                  1    
  97. X mapaux.c                  1    
  98. X mapit.c                   2    
  99. X mem.c                     1    
  100. X parse.y                   2    
  101. X pathalias.1               2    
  102. X printit.c                 1    
  103. END_OF_MANIFEST
  104. if test 714 -ne `wc -c <MANIFEST`; then
  105.     echo shar: \"MANIFEST\" unpacked with wrong size!
  106. fi
  107. # end of overwriting check
  108. fi
  109. if test -f Makefile -a "${1}" != "-c" ; then 
  110.   echo shar: Will not over-write existing file \"Makefile\"
  111. else
  112. echo shar: Extracting \"Makefile\" \(1364 characters\)
  113. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  114. X#!/bin/make -f
  115. X# pathalias -- by steve bellovin, as told to peter honeyman
  116. X
  117. X### configuration section
  118. X###
  119. X# if you can't or don't intend to use dbm files,
  120. X# don't bother with DBM or makedb
  121. XDBM = -ldbm
  122. X# or if you roll your own ...
  123. X# DBM = dbm.o
  124. X###
  125. X# where is getopt (if not in the c library)?
  126. X# GETOPT = getopt.o
  127. X### end of configuration section 
  128. X
  129. X
  130. XCC = cc
  131. XCFLAGS = -O -DSTATIC=static
  132. XLDFLAGS = -s $(GETOPT)
  133. XYFLAGS = -d
  134. X
  135. XOBJ = addlink.o addnode.o local.o main.o mapit.o mapaux.o mem.o parse.o printit.o
  136. XHDRS = def.h config.h
  137. XCSRC = addlink.c addnode.c local.c main.c mapit.c mapaux.c mem.c printit.c
  138. XLSRC = $(CSRC) parse.c
  139. XSRC = $(CSRC) parse.y makedb.c arpatxt.c
  140. X
  141. Xpathalias: $(OBJ)
  142. X    $(CC) $(OBJ) $(LDFLAGS) -o pathalias
  143. X
  144. Xall: pathalias makedb arpatxt
  145. X
  146. X$(OBJ):    $(HDRS)
  147. X
  148. Xparse.c: parse.y $(HDRS)
  149. X    $(YACC) $(YFLAGS) parse.y
  150. X    mv y.tab.c parse.c
  151. X
  152. Xmakedb: makedb.o
  153. X    $(CC) makedb.o $(LDFLAGS) $(DBM) -o makedb
  154. X
  155. Xmakedb.o: config.h
  156. X
  157. Xarpatxt: arpatxt.o
  158. X    $(CC) arpatxt.o $(LDFLAGS) -o arpatxt
  159. X
  160. Xclean:
  161. X    rm -f *.o y.tab.? parse.c
  162. X
  163. Xclobber: clean
  164. X    rm -f pathalias makedb arpatxt
  165. X
  166. Xtags: $(SRC) $(HDRS)
  167. X    ctags -w $(HDRS) $(SRC)
  168. X
  169. Xbundle:
  170. X    @bundle README CHANGES pathalias.1 Makefile ${HDRS} ${SRC}
  171. X
  172. Xlint:    $(LSRC)
  173. X    lint $(CFLAGS) $(LSRC)
  174. X    lint makedb.c
  175. X    lint arpatxt.c
  176. X
  177. Xinstall:
  178. X    @echo "install pathalias, makedb, arpatxt, and pathalias.1"
  179. X    @echo "according to local conventions"
  180. END_OF_Makefile
  181. if test 1364 -ne `wc -c <Makefile`; then
  182.     echo shar: \"Makefile\" unpacked with wrong size!
  183. fi
  184. # end of overwriting check
  185. fi
  186. if test -f README -a "${1}" != "-c" ; then 
  187.   echo shar: Will not over-write existing file \"README\"
  188. else
  189. echo shar: Extracting \"README\" \(1073 characters\)
  190. sed "s/^X//" >README <<'END_OF_README'
  191. XFrom citi!honey Sun Oct  4 23:30 EDT 1987
  192. XDate: 04 Oct 1987 23:30 EDT
  193. XFrom: honey@citi.umich.edu
  194. XTo: whom it may concern
  195. XSubject: pathalias compilation instructions
  196. X
  197. Xedit config.h
  198. Xmake
  199. X
  200. Xif getopt is undefined, obtain a copy from usenet group
  201. Xcomp.sources.unix and adjust Makefile.
  202. X
  203. Xpathalias input is regularly published in usenet group comp.mail.maps.
  204. X
  205. X    peter
  206. X
  207. Xps:  pathalias, written by steve bellovin and peter honeyman, is in the
  208. X     public domain, and may be used by any person or organization, in
  209. X     any way and for any purpose.
  210. X
  211. Xpps:  There is no warranty of merchantability nor any warranty of fit-
  212. X      ness for a particular purpose nor any other warranty, either ex-
  213. X      press or implied, as to the accuracy of the enclosed materials or
  214. X      as to their suitability for any particular purpose.  Accordingly,
  215. X      the authors assume no responsibility for their use by the recipi-
  216. X      ent.   Further, the authors assume no obligation to furnish any
  217. X      assistance of any kind whatsoever, or to furnish any additional
  218. X      information or documentation.
  219. END_OF_README
  220. if test 1073 -ne `wc -c <README`; then
  221.     echo shar: \"README\" unpacked with wrong size!
  222. fi
  223. # end of overwriting check
  224. fi
  225. if test -f addlink.c -a "${1}" != "-c" ; then 
  226.   echo shar: Will not over-write existing file \"addlink.c\"
  227. else
  228. echo shar: Extracting \"addlink.c\" \(4693 characters\)
  229. sed "s/^X//" >addlink.c <<'END_OF_addlink.c'
  230. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  231. X#ifndef lint
  232. Xstatic char    *sccsid = "@(#)addlink.c    9.1 87/10/04";
  233. X#endif /* lint */
  234. X
  235. X#include "def.h"
  236. X
  237. X/* exports */
  238. Xextern link *addlink();
  239. Xextern void deadlink(), atrace();
  240. Xextern int tracelink();
  241. Xchar *Netchars = "!:@%";    /* sparse, but sufficient */
  242. Xlong Lcount;            /* how many edges? */
  243. X
  244. X
  245. X/* imports */
  246. Xextern int Tflag, Dflag;
  247. Xextern link *newlink();
  248. Xextern node *addnode();
  249. Xextern void yyerror(), die();
  250. X
  251. X/* privates */
  252. XSTATIC void netbits(), ltrace(), ltrprint();
  253. Xstatic link    *Trace[NTRACE];
  254. Xstatic int    Tracecount;
  255. X
  256. Xlink *
  257. Xaddlink(from, to, cost, netchar, netdir)
  258. X    node *from;
  259. X    register node *to;
  260. X    Cost cost;
  261. X    char netchar, netdir;
  262. X{    register link *l, *prev = 0;
  263. X
  264. X    if (Tflag)
  265. X        ltrace(from, to, cost, netchar, netdir);
  266. X    /*
  267. X     * maintain uniqueness for dead links (only).
  268. X     */
  269. X    for (l = from->n_link; l; l = l->l_next) {
  270. X        if (!(l->l_flag & LDEAD))
  271. X            break;
  272. X        if (to == l->l_to) {
  273. X            /* what the hell, use cheaper dead cost */
  274. X            if (cost < l->l_cost) {
  275. X                l->l_cost = cost;
  276. X                netbits(l, netchar, netdir);
  277. X            }
  278. X            return l;
  279. X        }
  280. X        prev = l;
  281. X    }
  282. X    
  283. X
  284. X    /* allocate and link in the new link struct */
  285. X    l = newlink();
  286. X    if (cost != INF)    /* ignore back links */
  287. X        Lcount++;
  288. X    if (prev) {
  289. X        l->l_next = prev->l_next;
  290. X        prev->l_next = l;
  291. X    } else {
  292. X        l->l_next = from->n_link;
  293. X        from->n_link = l;
  294. X    }
  295. X
  296. X    l->l_to = to;
  297. X    l->l_cost = cost + from->n_cost;    /* add penalty */
  298. X    if (netchar == 0) {
  299. X        netchar = DEFNET;
  300. X        netdir = DEFDIR;
  301. X    }
  302. X    netbits(l, netchar, netdir);
  303. X    if (Dflag && ISADOMAIN(from) && !ISADOMAIN(to))
  304. X        l->l_flag |= LTERMINAL;
  305. X
  306. X    return l;
  307. X}
  308. X
  309. Xvoid
  310. Xdeadlink(nleft, nright) 
  311. X    node *nleft, *nright;
  312. X{    link *l, *lhold = 0, *lprev, *lnext;
  313. X
  314. X    /* DEAD host */
  315. X    if (nright == 0) {
  316. X        nleft->n_flag |= NDEAD;        /* DEAD host */
  317. X        return;
  318. X    }
  319. X
  320. X    /* DEAD link */
  321. X
  322. X    /* grab <nleft, nright> instances at head of nleft adjacency list */
  323. X    while ((l = nleft->n_link) != 0 && l->l_to == nright) {
  324. X        nleft->n_link = l->l_next;    /* disconnect */
  325. X        l->l_next = lhold;        /* terminate */
  326. X        lhold = l;            /* add to lhold */
  327. X    }
  328. X
  329. X    /* move remaining <nleft, nright> instances */
  330. X    for (lprev = nleft->n_link; lprev && lprev->l_next; lprev = lprev->l_next) {
  331. X        if (lprev->l_next->l_to == nright) {
  332. X            l = lprev->l_next;
  333. X            lprev->l_next = l->l_next;    /* disconnect */
  334. X            l->l_next = lhold;        /* terminate */
  335. X            lhold = l;
  336. X        }
  337. X    }
  338. X
  339. X    /* check for emptiness */
  340. X    if (lhold == 0) {
  341. X        addlink(nleft, nright, INF / 2, DEFNET, DEFDIR)->l_flag |= LDEAD;
  342. X        return;
  343. X    }
  344. X
  345. X    /* reinsert deleted edges as DEAD links */
  346. X    for (l = lhold; l; l = lnext) {
  347. X        lnext = l->l_next;
  348. X        addlink(nleft, nright, l->l_cost, NETCHAR(l), NETDIR(l))->l_flag |= LDEAD;
  349. X        freelink(l);
  350. X    }
  351. X}
  352. X
  353. XSTATIC void
  354. Xnetbits(l, netchar, netdir)
  355. X    register link *l;
  356. X    char netchar, netdir;
  357. X{
  358. X    l->l_flag &= ~LDIR;
  359. X    l->l_flag |= netdir;
  360. X    l->l_netop = netchar;
  361. X}
  362. X
  363. Xint
  364. Xtracelink(arg) 
  365. X    char *arg;
  366. X{    char *bang;
  367. X    link *l;
  368. X
  369. X    if (Tracecount >= NTRACE)
  370. X        return -1;
  371. X    l = newlink();
  372. X    bang = index(arg, '!');
  373. X    if (bang) {
  374. X        *bang = 0;
  375. X        l->l_to = addnode(bang+1);
  376. X    } else 
  377. X        l->l_to = 0;
  378. X
  379. X    l->l_from = addnode(arg);
  380. X    Trace[Tracecount++] = l;
  381. X    return 0;
  382. X}
  383. X
  384. XSTATIC void
  385. Xltrace(from, to, cost, netchar, netdir)
  386. X    node *from, *to;
  387. X    Cost cost;
  388. X    char netchar, netdir;
  389. X{    link *l;
  390. X    int i;
  391. X
  392. X    for (i = 0; i < Tracecount; i++) {
  393. X        l = Trace[i];
  394. X        /* overkill, but you asked for it! */
  395. X        if ((l->l_to == 0
  396. X          && (from == (node *) l->l_from || to == (node *) l->l_from))
  397. X         || (from == (node *) l->l_from && to == l->l_to)
  398. X         || (to == (node *) l->l_from && from == l->l_to)) {
  399. X            ltrprint(from, to, cost, netchar, netdir);
  400. X            return;
  401. X        }
  402. X    }
  403. X}
  404. X
  405. X/* print a trace item */
  406. XSTATIC void
  407. Xltrprint(from, to, cost, netchar, netdir)
  408. X    node *from, *to;
  409. X    Cost cost;
  410. X    char netchar;
  411. X    char netdir;
  412. X{    char buf[256], *bptr = buf;
  413. X
  414. X    strcpy(bptr, from->n_name);
  415. X    bptr += strlen(bptr);
  416. X    *bptr++ = ' ';
  417. X    if (netdir == LRIGHT)            /* @% */
  418. X        *bptr++ = netchar;
  419. X    strcpy(bptr, to->n_name);
  420. X    bptr += strlen(bptr);
  421. X    if (netdir == LLEFT)            /* !: */
  422. X        *bptr++ = netchar;
  423. X    sprintf(bptr, "(%ld)", cost);
  424. X    yyerror(buf);
  425. X}
  426. X
  427. Xvoid
  428. Xatrace(n1, n2)
  429. X    node *n1, *n2;
  430. X{    link *l;
  431. X    int i;
  432. X    char buf[256];
  433. X
  434. X    for (i = 0; i < Tracecount; i++) {
  435. X        l = Trace[i];
  436. X        if (l->l_to == 0 && ((node *) l->l_from == n1 || (node *) l->l_from == n2)) {
  437. X            sprintf(buf, "%s = %s", n1->n_name, n2->n_name);
  438. X            yyerror(buf);
  439. X            return;
  440. X        }
  441. X    }
  442. X}
  443. X
  444. X#define EQ(n1, n2) strcmp(n1->n_name, n2->n_name) == 0
  445. Xmaptrace(from, to)
  446. X    register node *from, *to;
  447. X{    register link *l;
  448. X    register int i;
  449. X
  450. X    for (i = 0; i < Tracecount; i++) {
  451. X        l = Trace[i];
  452. X        if (l->l_to == 0) {
  453. X            if (EQ(from, l->l_from) || EQ(to, l->l_from))
  454. X                return 1;
  455. X        } else if (EQ(from, l->l_from) && EQ(to, l->l_to))
  456. X                return 1;
  457. X    }
  458. X    return 0;
  459. X}
  460. END_OF_addlink.c
  461. if test 4693 -ne `wc -c <addlink.c`; then
  462.     echo shar: \"addlink.c\" unpacked with wrong size!
  463. fi
  464. # end of overwriting check
  465. fi
  466. if test -f arpa-privates -a "${1}" != "-c" ; then 
  467.   echo shar: Will not over-write existing file \"arpa-privates\"
  468. else
  469. echo shar: Extracting \"arpa-privates\" \(4636 characters\)
  470. sed "s/^X//" >arpa-privates <<'END_OF_arpa-privates'
  471. X###
  472. X#host        map file ([map file ...] for unregistered hosts)
  473. X#
  474. Xabbott        usa.ca
  475. Xabel        usa.ca
  476. Xachilles    usa.nj.a
  477. Xacorn        gbr
  478. Xadam        [usa.il.a]
  479. Xadams        swe
  480. Xadmin        [usa.ut]
  481. Xads        [usa.ca]
  482. Xai        gbr
  483. Xalamo        usa.tx
  484. Xalpha        usa.in
  485. Xamc        usa.wa
  486. Xames        usa.ca (amazingly ...)
  487. Xamon        swe
  488. Xamos        [usa.ca?]
  489. Xanimal        usa.nj.a
  490. Xanubis        usa.il
  491. Xapollo        usa.ma
  492. Xaramis        usa.nj
  493. Xargus        usa.nj
  494. Xariadne        grc
  495. Xarthur        [usa.oh]
  496. Xasgard        usa.or
  497. Xastro        [usa.ma]
  498. Xathena        usa.or
  499. Xatlantis    usa.nj.a
  500. Xatlas        usa.oh.a
  501. Xaurora        [usa.ca]
  502. Xb21        deu
  503. Xbach        [usa.nc]
  504. Xbalder        [usa.oh]
  505. Xbashful        [usa.nc]
  506. Xbeaver        [usa.pa?]
  507. Xbishop        gbr
  508. Xbluebell    usa.ca
  509. Xbluto        [usa.tx?]
  510. Xbonnie        usa.nj.a
  511. Xboojum        usa.nj.a
  512. Xbosco        [esp]
  513. Xbourbaki    usa.il
  514. Xbozo        usa.nj.a
  515. Xbrahms        asia.japan
  516. Xcalico        usa.ny
  517. Xcantor        [usa.il]
  518. Xcapella        swe
  519. Xcastor        usa.nj.a
  520. Xcdr        [usa.mi]
  521. Xcerberus    [usa.il?]
  522. Xchaos        usa.ok
  523. Xcirce        usa.nj.a
  524. Xclara        usa.ny
  525. Xclark        usa.nj.a
  526. Xcleo        usa.nj.b
  527. Xclutx        [usa.fl?, usa.ny?]
  528. Xcogito        usa.nj.a
  529. Xcolby        usa.me
  530. Xcomet        usa.or
  531. Xcondor        usa.ma
  532. Xcottage        [gbr]
  533. Xcsab        [usa.il?]
  534. Xcsd1        usa.ny
  535. Xcsd2        usa.ny
  536. Xcsvax        [usa.mn]
  537. Xcti        usa.ca
  538. Xdanger        can.ab
  539. Xdarwin        can.on
  540. Xdcn1        [usa.ca?]
  541. Xdeimos          [usa.il.a, usa.a]
  542. Xdelphi        ita
  543. Xdev        usa.md
  544. Xdewey        usa.nj.a
  545. Xdickens        [can.bc?]
  546. Xdiomedes    usa.nj.a
  547. Xdoc        [usa.nc]
  548. Xdopey        [usa.nc]
  549. Xea        usa.ok
  550. Xearth        usa.nj.a
  551. Xed        gbr
  552. Xeddie        [gbr]
  553. Xedith        [usa.oh]
  554. Xeinstein    usa.ny
  555. Xelse        [jpn]
  556. Xems        usa.mn
  557. Xerc        gbr
  558. Xernie        [usa.oh]
  559. Xescher        usa.ca
  560. Xeuclid        [gbr]
  561. Xeuler        usa.nj
  562. Xeunice        usa.fl
  563. Xeuropa        [usa.ri]
  564. Xexcalibur    usa.pa
  565. Xfelix        usa.ca
  566. Xfermat        usa.nj
  567. Xfifi        [usa.tx]
  568. Xfisher        usa.nj
  569. Xflash        [can.on]
  570. Xfloyd        usa.nj.a
  571. Xfluke        usa.wa
  572. Xforest        [usa.tx]
  573. Xfred        usa.co
  574. Xfrog        usa.ma
  575. Xgalileo        [usa.mo]
  576. Xgamma        usa.nj.b
  577. Xgandalf        can.on
  578. Xgarfield    can.nf
  579. Xgateway        usa.ny
  580. Xgizmo        [usa.ca?, usa.il?]
  581. Xgodot        usa.nc
  582. Xgolem        usa.ca
  583. Xgonzo        [usa.a?, usa.ca?]
  584. Xgould        usa.fl
  585. Xgranite        [usa.nh]
  586. Xgreen        usa.md
  587. Xgrendel        usa.nj.a
  588. Xgrumpy        [usa.ga.a, usa.il.a, usa.a, usa.nc]
  589. Xhamlet        [usa.nj.a]
  590. Xhappy        [usa.nc]
  591. Xhaven        usa.ct
  592. Xhawaii        usa.hi
  593. Xhawk        [usa.ca?
  594. Xhelios        [usa.ca]
  595. Xhermes        usa.il.a
  596. Xhilbert        usa.wa
  597. Xhollywood    [usa.ca?]
  598. Xhorus        [usa.ca?]
  599. Xhottub        [usa.ca]
  600. Xhub        [usa.tx]
  601. Xhudson        usa.nj.a
  602. Xhuey        usa.nj.a
  603. Xicarus        usa.nj.a
  604. Xicsd        usa.fl.a
  605. Xindra        usa.nj.b
  606. Xintech        [gbr]
  607. Xio        usa.nj.a
  608. Xipac        [usa.az?, usa.ca?]
  609. Xiris        usa.ri
  610. Xisis        usa.co
  611. Xjack        usa.ca
  612. Xjaguar        [usa.il.a]
  613. Xjanus        [usa.ca]
  614. Xjason        usa.ny
  615. Xjenkins        [usa.tx]
  616. Xjim        [usa.ga.a, usa.il.a]
  617. Xjoey        usa.pa.a
  618. Xjove        usa.ny
  619. Xjuliet        [usa.nj.a, usa.nj]
  620. Xkaos        [usa.il]
  621. Xkermit        usa.nj.a
  622. Xkobold        [usa.ca]
  623. Xkronos        grc
  624. Xlafite        usa.nj.b
  625. Xlarry        [usa.tx, usa.ma]
  626. Xleg        [fra]
  627. Xlego        dmk
  628. Xleopard        usa.nj.b
  629. Xlilac        kor
  630. Xlinus        usa.ma
  631. Xlion        usa.nj.b
  632. Xlouie        usa.nj.a
  633. Xludwig        usa.nj.a
  634. Xlynx        [usa.ca]
  635. Xmadvax        usa.ca
  636. Xmagic        [usa.mo, usa.nj.b]
  637. Xmanx        usa.nj
  638. Xmariner        usa.nj.a
  639. Xmarvin        gbr
  640. Xmath        [usa.or]
  641. Xmaui        usa.va
  642. Xmax        usa.nj.a
  643. Xmaxwell        usa.mo
  644. Xmedea        [[usa.mi]]
  645. Xmegalon        deu
  646. Xmerlin        usa.nj.a
  647. Xmhuxc        usa.nj.a
  648. Xmickey        [usa.nj]
  649. Xmilo        usa.md
  650. Xminnie        usa.co
  651. Xmiranda        usa.nj.a
  652. Xnemesis        [usa.ca]
  653. Xnemo        [usa.mo]
  654. Xnetman        usa.oh.a
  655. Xnexus        [can.ab, fra]
  656. Xnyquist        usa.nj.b
  657. Xoac        usa.nj.a
  658. Xoak        [usa.ct]
  659. Xocean        [usa.ca]
  660. Xodin        usa.nj.a
  661. Xomega        usa.nj.a
  662. Xopus        [usa.a, usa.ga, usa.il.a]
  663. Xorion        usa.nj.a
  664. Xorville        usa.ny
  665. Xosiris        usa.md
  666. Xotto        usa.nv
  667. Xoz        usa.wa
  668. Xpallas        usa.il
  669. Xpandora        usa.nj.b
  670. Xpelican        usa.ca
  671. Xphobos        usa.nj.a
  672. Xphoenix        usa.nj.a
  673. Xphysics        usa.nj.a
  674. Xpilchuck    usa.wa
  675. Xpine        kor
  676. Xpioneer        [usa.il.a]
  677. Xplasma        usa.pa.a
  678. Xpluto        usa.ny
  679. Xpolaris        usa.ny
  680. Xpolya        usa.nj.a
  681. Xposeidon    usa.nj.a
  682. Xpostel        nld
  683. Xpresto        usa.md
  684. Xpriam        [che]
  685. Xprinceton    usa.nj (stupid!)
  686. Xprism        usa.nj
  687. Xprometheus    usa.md
  688. Xpsc        usa.md
  689. Xpsyche        usa.nc
  690. Xpuma        gbr
  691. Xqat        [usa.tx]
  692. Xra        usa.ny
  693. Xrainier        swe
  694. Xralph        [usa.tx]
  695. Xranger        [usa.il.a]
  696. Xredwood        [usa.ca]
  697. Xridge        usa.ca
  698. Xrigel        usa.ny
  699. Xrose        usa.nj.a
  700. Xrover        [usa.ma]
  701. Xrsch        [usa.ma?]
  702. Xsabre        usa.nj.b
  703. Xsal        [swe]
  704. Xsales        usa.a
  705. Xsamwise        usa.nj.a
  706. Xsaturn        usa.oh.a
  707. Xscience        [usa.nj.b]
  708. Xsds        [usa.mn]
  709. Xshark        usa.or
  710. Xshrike        [usa.tx]
  711. Xsimon        [usa.il?]
  712. Xsleepy        [usa.nc]
  713. Xsneezy        [usa.wi]
  714. Xsnoopy        [gbr]
  715. Xsol        [usa.il.a, usa.ny, gbr]
  716. Xsolar        usa.nm
  717. Xspam        usa.nj
  718. Xsphinx        usa.il
  719. Xstar        [usa.ca?, usa.il.a?, usa.nj.b?]
  720. Xstars        can.ns
  721. Xstc        gbr
  722. Xstuart        [usa.md]
  723. Xsunrise        usa.nj
  724. Xsuper        usa.md
  725. Xsurya        usa.ca
  726. Xtb        usa.ok.a
  727. Xterminus    [usa.oh?, usa.wi?]
  728. Xterra        usa.ma
  729. Xthor        dmk
  730. Xthunder        can.on
  731. Xthyme        usa.ca
  732. Xtiger        usa.nj
  733. Xtitan        usa.ca
  734. Xtrillian    usa.nj.a
  735. Xtriton        [jpn, usa.or]
  736. Xtut        fin
  737. Xubvax        usa.ca
  738. Xulysses        usa.nj.a
  739. Xunh        usa.nh
  740. Xunicorn        usa.nj.a
  741. Xunix        [usa.or]
  742. Xunix3        [usa.ga.a, usa.il.a]
  743. Xusadhq2        [usa.ca?]
  744. Xusafa        [usa.co?, usa.fl?, usa.nh?]
  745. Xvalid        [usa.ca]
  746. Xvax1        [gbr]
  747. Xvax2        [gbr]
  748. Xvega        swe
  749. Xvenice        usa.ca.a
  750. Xvictoria    can.on
  751. Xvortex        usa.ca
  752. Xvoyager        [usa.il.a]
  753. Xwang        usa.ma
  754. Xwayback        usa.nj.a
  755. Xwimsey        usa.nj.a
  756. Xwombat        usa.nj.a
  757. Xzaphod        can.sk
  758. Xzeta        usa.nj.b
  759. Xzorac        can.on
  760. END_OF_arpa-privates
  761. if test 4636 -ne `wc -c <arpa-privates`; then
  762.     echo shar: \"arpa-privates\" unpacked with wrong size!
  763. fi
  764. # end of overwriting check
  765. fi
  766. if test -f config.h -a "${1}" != "-c" ; then 
  767.   echo shar: Will not over-write existing file \"config.h\"
  768. else
  769. echo shar: Extracting \"config.h\" \(2061 characters\)
  770. sed "s/^X//" >config.h <<'END_OF_config.h'
  771. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  772. X
  773. X#undef STRCHR        /* have strchr -- system v and many others */
  774. X
  775. X#undef UNAME        /* have uname() -- probably system v or 8th ed. */
  776. X#undef MEMSET        /* have memset() -- probably system v or 8th ed. */
  777. X
  778. X#define GETHOSTNAME    /* have gethostname() -- probably bsd */
  779. X#define BZERO        /* have bzero() -- probably bsd */
  780. X
  781. X/* default place for dbm output of makedb (or use -o at run-time) */
  782. X#define    ALIASDB    "/usr/local/lib/palias"
  783. X
  784. X
  785. X
  786. X/**************************************************************************
  787. X *                                      *
  788. X * +--------------------------------------------------------------------+ *
  789. X * |                                    | *
  790. X * |            END OF CONFIGURATION SECTION            | *
  791. X * |                                    | *
  792. X * |                EDIT NO MORE                | *
  793. X * |                                    | *
  794. X * +--------------------------------------------------------------------+ *
  795. X *                                      *
  796. X **************************************************************************/
  797. X
  798. X#ifdef MAIN
  799. X#ifndef lint
  800. Xstatic char    *c_sccsid = "@(#)config.h    9.1 87/10/04";
  801. X#endif /*lint*/
  802. X#endif /*MAIN*/
  803. X
  804. X/*
  805. X * malloc/free fine tuned for pathalias.
  806. X *
  807. X * MYMALLOC should work everwhere, so it's not a configuration
  808. X * option (anymore).  nonetheless, if you're getting strange
  809. X * core dumps (or panics!), comment out the following manifest,
  810. X * and use the inferior C library malloc/free.
  811. X *
  812. X * please report problems to citi!honey or honey@citi.umich.edu.
  813. X */
  814. X#define MYMALLOC    /**/
  815. X
  816. X#ifdef MYMALLOC
  817. X#define malloc mymalloc
  818. X#define calloc(n, s) malloc ((n)*(s))
  819. X#define free(s)
  820. X#define cfree(s)
  821. Xextern char *memget();
  822. X#else /* !MYMALLOC */
  823. Xextern char *calloc();
  824. X#endif /* MYMALLOC */
  825. X
  826. X#ifdef STRCHR
  827. X#define index strchr
  828. X#define rindex strrchr
  829. X#else
  830. X#define strchr index
  831. X#define strrchr rindex
  832. X#endif
  833. X
  834. X#ifdef BZERO
  835. X#define strclear(s, n)    ((void) bzero((s), (n)))
  836. X#else /*!BZERO*/
  837. X
  838. X#ifdef MEMSET
  839. Xextern char    *memset();
  840. X#define strclear(s, n)    ((void) memset((s), 0, (n)))
  841. X#else /*!MEMSET*/
  842. Xextern void    strclear();
  843. X#endif /*MEMSET*/
  844. X
  845. X#endif /*BZERO*/
  846. X
  847. Xextern char    *malloc();
  848. Xextern char    *strcpy(), *index(), *rindex();
  849. END_OF_config.h
  850. if test 2061 -ne `wc -c <config.h`; then
  851.     echo shar: \"config.h\" unpacked with wrong size!
  852. fi
  853. # end of overwriting check
  854. fi
  855. if test -f def.h -a "${1}" != "-c" ; then 
  856.   echo shar: Will not over-write existing file \"def.h\"
  857. else
  858. echo shar: Extracting \"def.h\" \(4366 characters\)
  859. sed "s/^X//" >def.h <<'END_OF_def.h'
  860. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  861. X
  862. X#ifndef lint
  863. X#ifdef MAIN
  864. Xstatic char    *h_sccsid = "@(#)def.h    9.1 87/10/04";
  865. X#endif /*MAIN*/
  866. X#endif /*lint*/
  867. X
  868. X#include <stdio.h>
  869. X#include <ctype.h>
  870. X#include "config.h"
  871. X
  872. Xtypedef    long Cost;
  873. Xtypedef struct node node;
  874. Xtypedef struct link link;
  875. X
  876. X#ifdef lint
  877. X#define vprintf fprintf
  878. X#else /*!lint -- this gives null effect warning*/
  879. X/* because it's there ... */
  880. X#define vprintf        !Vflag ? 0 : fprintf
  881. X#endif /*lint*/
  882. X
  883. X#define NTRACE    16    /* can trace up to NTRACE hosts/links */
  884. X
  885. X/* scanner states (yylex, parse) */
  886. X#define OTHER    0
  887. X#define COSTING    1
  888. X#define NEWLINE    2
  889. X
  890. X/* flags for n_flag */
  891. X#define ISPRIVATE  0x0001 /* invisible outside its definition file */
  892. X#define NALIAS       0x0002 /* heaped as an alias */
  893. X#define ATSIGN       0x0004 /* seen an at sign?  used for magic @/% rules */
  894. X#define MAPPED       0x0008 /* extracted from heap */
  895. X#define    NDEAD       0x0010 /* out links are dead */
  896. X#define HASLEFT       0x0020 /* has a left side net character */
  897. X#define HASRIGHT   0x0040 /* route has a right side net character */
  898. X#define    NNET       0x0080 /* network pseudo-host */
  899. X#define INDFS       0x0100 /* used when removing net cycles (for -g) */
  900. X#define DUMP       0x0200 /* we have dumped this net's edges (for -g) */
  901. X#define PRINTED       0x0400 /* this host has been printed */
  902. X#define NTERMINAL  0x0800 /* heaped as terminal edge (or alias thereto) */
  903. X
  904. X#define ISADOMAIN(n) ((n)->n_name[0] == '.')
  905. X#define ISANET(n) (((n)->n_flag & NNET) || ISADOMAIN(n))
  906. X#define DEADHOST(n) ((((n)->n_flag & (NNET | NDEAD)) == NDEAD) || (n->n_flag & NTERMINAL))
  907. X#define GATEWAYED(n) (((n)->n_flag & (NNET | NDEAD)) == (NNET | NDEAD) || ISADOMAIN(n))
  908. X
  909. X#ifndef DEBUG
  910. X/*
  911. X * save some space in nodes -- there are > 10,000 allocated!
  912. X */
  913. X
  914. X#define n_root un1.nu_root
  915. X#define n_net un1.nu_net
  916. X#define n_copy un1.nu_copy
  917. X
  918. X#define n_private un2.nu_priv
  919. X#define n_parent  un2.nu_par
  920. X
  921. X/* WARNING: if > 2^16 nodes, type of n_tloc must change */
  922. Xstruct node {
  923. X    char    *n_name;    /* host name */
  924. X    link    *n_link;    /* adjacency list */
  925. X    Cost    n_cost;        /* cost to this host */
  926. X    union {
  927. X        node *nu_net;    /* others in this network (parsing) */
  928. X        node *nu_root;    /* root of net cycle (graph dumping) */
  929. X        node *nu_copy;    /* circular copy list (mapping) */
  930. X    } un1;
  931. X    union {
  932. X        node *nu_priv;    /* other privates in this file (parsing) */
  933. X        node *nu_par;    /* parent in shortest path tree (mapping) */
  934. X    } un2;
  935. X    unsigned short n_tloc;    /* back ptr to heap/hash table */
  936. X    unsigned short n_flag;        /* see manifests above */
  937. X};
  938. X
  939. X#endif /*DEBUG*/
  940. X
  941. X#define    DEFNET    '!'            /* default network operator */
  942. X#define    DEFDIR    LLEFT            /* host on left is default */
  943. X#define    DEFCOST    ((Cost) 4000)        /* default cost of a link */
  944. X#define    INF    ((Cost) 30000000)    /* infinitely expensive link */
  945. X#define DEFPENALTY ((Cost) 200)        /* default avoidance cost */
  946. X
  947. X/* data structure for adjacency list representation */
  948. X
  949. X/* flags for l_dir */
  950. X
  951. X#define NETDIR(l)    ((l)->l_flag & LDIR)
  952. X#define NETCHAR(l)    ((l)->l_netop)
  953. X
  954. X#define LDIR      0x0008    /* 0 for left, 1 for right */
  955. X#define LRIGHT      0x0000    /* user@host style */
  956. X#define LLEFT      0x0008    /* host!user style */
  957. X
  958. X#define LDEAD      0x0010    /* this link is dead */
  959. X#define LALIAS      0x0020    /* this link is an alias */
  960. X#define LTREE      0x0040    /* member of shortest path tree */
  961. X#define LGATEWAY  0x0080    /* this link is a gateway */
  962. X#define LTERMINAL 0x0100    /* this link is terminal */
  963. X
  964. X#ifndef DEBUG
  965. X/*
  966. X * borrow a field for link/node tracing.  there's a shitload of
  967. X * edges -- every word counts.  only so much squishing is possible:
  968. X * alignment dictates that the size be a multiple of four.
  969. X */
  970. X
  971. X#define l_next un.lu_next
  972. X#define l_from un.lu_from
  973. X
  974. Xstruct link {
  975. X    node    *l_to;        /* adjacent node */
  976. X    Cost    l_cost;        /* edge cost */
  977. X    union {
  978. X        link *lu_next;    /* rest of adjacency list (not tracing) */
  979. X        node *lu_from;    /* source node (tracing) */
  980. X    } un;
  981. X    short    l_flag;        /* right/left syntax, flags */
  982. X    char    l_netop;    /* network operator */
  983. X};
  984. X
  985. X#endif /*DEBUG*/
  986. X
  987. X#ifdef DEBUG
  988. X/*
  989. X * flattening out the unions makes it easier
  990. X * to debug (when pi is unavailable).
  991. X */
  992. Xstruct node {
  993. X    char    *n_name;
  994. X    link    *n_link;
  995. X    Cost    n_cost;
  996. X    node    *n_net;
  997. X    node    *n_root;
  998. X    node    *n_copy;
  999. X    node    *n_private;
  1000. X    node    *n_parent;
  1001. X    unsigned short n_tloc;
  1002. X    unsigned short n_flag;
  1003. X};
  1004. Xstruct link {
  1005. X    node    *l_to;
  1006. X    Cost    l_cost;
  1007. X    link    *l_next;
  1008. X    node    *l_from;
  1009. X    short    l_flag;
  1010. X    char    l_netop;
  1011. X};
  1012. X#endif /*DEBUG*/
  1013. END_OF_def.h
  1014. if test 4366 -ne `wc -c <def.h`; then
  1015.     echo shar: \"def.h\" unpacked with wrong size!
  1016. fi
  1017. # end of overwriting check
  1018. fi
  1019. if test -f local.c -a "${1}" != "-c" ; then 
  1020.   echo shar: Will not over-write existing file \"local.c\"
  1021. else
  1022. echo shar: Extracting \"local.c\" \(1420 characters\)
  1023. sed "s/^X//" >local.c <<'END_OF_local.c'
  1024. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  1025. X#ifndef lint
  1026. Xstatic char    *sccsid = "@(#)local.c    9.1 87/10/04";
  1027. X#endif /* lint */
  1028. X
  1029. X#include <stdio.h>
  1030. X#include "config.h"
  1031. X
  1032. X#ifdef    UNAME
  1033. X#include <sys/utsname.h>
  1034. X
  1035. Xchar    *
  1036. Xlocal()
  1037. X{
  1038. X    static struct utsname utsname;
  1039. X
  1040. X    uname(&utsname);
  1041. X    return(utsname.nodename);
  1042. X}
  1043. X
  1044. X#else /* !UNAME */
  1045. X
  1046. Xchar    *
  1047. Xlocal()
  1048. X{
  1049. X    static char lname[64];
  1050. X
  1051. X    gethostname(lname, sizeof(lname));
  1052. X    return(lname);
  1053. X}
  1054. X
  1055. X#ifndef GETHOSTNAME
  1056. X
  1057. Xstatic
  1058. Xgethostname(name, len)
  1059. Xchar    *name;
  1060. X{
  1061. X    FILE    *whoami, *fopen(), *popen();
  1062. X    char    *ptr, *index();
  1063. X
  1064. X    *name = '\0';
  1065. X
  1066. X    /* try /etc/whoami */
  1067. X    if ((whoami = fopen("/etc/whoami", "r")) != 0) {
  1068. X        (void) fgets(name, len, whoami);
  1069. X        (void) fclose(whoami);
  1070. X        if ((ptr = index(name, '\n')) != 0)
  1071. X            *ptr = '\0';
  1072. X    }
  1073. X    if (*name)
  1074. X        return 0;
  1075. X
  1076. X    /* try /usr/include/whoami.h */
  1077. X    if ((whoami = fopen("/usr/include/whoami.h", "r")) != 0) {
  1078. X        while (!feof(whoami)) {
  1079. X            char    buf[100];
  1080. X
  1081. X            if (fgets(buf, 100, whoami) == 0)
  1082. X                break;
  1083. X            if (sscanf(buf, "#define sysname \"%[^\"]\"", name))
  1084. X                break;
  1085. X        }
  1086. X        (void) fclose(whoami);
  1087. X        if (*name)
  1088. X            return 0;
  1089. X    }
  1090. X
  1091. X    /* ask uucp */
  1092. X    if ((whoami = popen("uuname -l", "r")) != 0) {
  1093. X        (void) fgets(name, len, whoami);
  1094. X        (void) pclose(whoami);
  1095. X        if ((ptr = index(name, '\n')) != 0)
  1096. X            *ptr = '\0';
  1097. X    }
  1098. X    if (*name)
  1099. X        return 0;
  1100. X    
  1101. X    /* aw hell, i give up!  is this really unix? */
  1102. X    return -1;
  1103. X}
  1104. X#endif /* GETHOSTNAME */
  1105. X#endif /* UNAME */
  1106. END_OF_local.c
  1107. if test 1420 -ne `wc -c <local.c`; then
  1108.     echo shar: \"local.c\" unpacked with wrong size!
  1109. fi
  1110. # end of overwriting check
  1111. fi
  1112. if test -f main.c -a "${1}" != "-c" ; then 
  1113.   echo shar: Will not over-write existing file \"main.c\"
  1114. else
  1115. echo shar: Extracting \"main.c\" \(3978 characters\)
  1116. sed "s/^X//" >main.c <<'END_OF_main.c'
  1117. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  1118. X#ifndef lint
  1119. Xstatic char    *sccsid = "@(#)main.c    9.1 87/10/04";
  1120. X#endif
  1121. X
  1122. X#define MAIN    /* for sccsid in header files */
  1123. X
  1124. X#include "def.h"
  1125. X
  1126. X/* exports */
  1127. Xextern void die();
  1128. Xchar *Cfile;    /* current input file */
  1129. Xchar *Graphout;    /* file for dumping edges (-g option) */
  1130. Xchar *Linkout;    /* file for dumping shortest path tree */
  1131. Xchar **Argv;    /* external copy of argv (for input files) */
  1132. Xnode *Home;    /* node for local host */
  1133. Xint Cflag;    /* print costs (-c option) */
  1134. Xint Dflag;    /* penalize routes beyond domains (-D option) */
  1135. Xint Iflag;    /* ignore case (-i option) */
  1136. Xint Tflag;    /* trace links (-t option) */
  1137. Xint Vflag;    /* verbose (-v option) */
  1138. Xint Fflag;    /* print cost of first hop */
  1139. Xint Lineno = 1;    /* line number within current input file */
  1140. Xint Argc;    /* external copy of argc (for input files) */
  1141. X
  1142. X/* imports */
  1143. Xextern long allocation();
  1144. Xextern void wasted(), mapit(), penalize(), hashanalyze(), deadlink();
  1145. Xextern char *local();
  1146. Xextern node *addnode();
  1147. Xextern char *optarg;
  1148. Xextern int optind;
  1149. Xextern long Lcount, Ncount;
  1150. X
  1151. X#define USAGE "usage: %s [-vciDf] [-l localname] [-d deadlink] [-t tracelink] [-g edgeout] [-s treeout] [-a avoid] [files ...]\n"
  1152. X
  1153. Xmain(argc, argv) 
  1154. X    register int argc; 
  1155. X    register char **argv;
  1156. X{    char *locname = 0, buf[32], *bang;
  1157. X    register int c;
  1158. X    int errflg = 0;
  1159. X
  1160. X    setbuf(stderr, (char *) 0);
  1161. X    (void) allocation();    /* initialize data space monitoring */
  1162. X    Cfile = "[deadlinks]";    /* for tracing dead links */
  1163. X    Argv = argv;
  1164. X    Argc = argc;
  1165. X
  1166. X    while ((c = getopt(argc, argv, "a:cd:Dfg:il:s:t:v")) != EOF)
  1167. X        switch(c) {
  1168. X        case 'a':    /* adjust cost out of arg */
  1169. X            penalize(optarg, DEFPENALTY);
  1170. X            break;
  1171. X        case 'c':    /* print cost info */
  1172. X            Cflag++;
  1173. X            break;
  1174. X        case 'd':    /* dead host or link */
  1175. X            if ((bang = index(optarg, '!')) != 0) {
  1176. X                *bang++ = 0;
  1177. X                deadlink(addnode(optarg), addnode(bang));
  1178. X            } else
  1179. X                deadlink(addnode(optarg), (node *) 0);
  1180. X            break;
  1181. X        case 'D':    /* penalize routes beyond domains */
  1182. X            Dflag++;
  1183. X            break;
  1184. X        case 'f':    /* print cost of first hop */
  1185. X            Cflag++;
  1186. X            Fflag++;
  1187. X            break;
  1188. X        case 'g':    /* graph output file */
  1189. X            Graphout = optarg;
  1190. X            break;
  1191. X        case 'i':    /* ignore case */
  1192. X            Iflag++;
  1193. X            break;
  1194. X        case 'l':    /* local name */
  1195. X            locname = optarg;
  1196. X            break;
  1197. X        case 's':    /* show shortest path tree */
  1198. X            Linkout = optarg;
  1199. X            break;
  1200. X        case 't':    /* trace this link */
  1201. X            if (tracelink(optarg) < 0) {
  1202. X                fprintf(stderr, "%s: can trace only %d links\n", Argv[0], NTRACE);
  1203. X                exit(1);
  1204. X            }
  1205. X            Tflag = 1;
  1206. X            break;
  1207. X        case 'v':    /* verbose stderr, mixed blessing */
  1208. X            Vflag++;
  1209. X            if (Vflag == 1) {
  1210. X                /* v8 pi snarf, benign EBADF elsewhere */
  1211. X                sprintf(buf, "/proc/%05d\n", getpid());
  1212. X                write(3, buf, strlen(buf));
  1213. X            }
  1214. X            break;
  1215. X        default:
  1216. X            errflg++;
  1217. X        }
  1218. X
  1219. X    if (errflg) {
  1220. X        fprintf(stderr, USAGE, Argv[0]);
  1221. X        exit(1);
  1222. X    }
  1223. X    argv += optind;        /* kludge for yywrap() */
  1224. X
  1225. X    if (*argv)
  1226. X        freopen("/dev/null", "r", stdin);
  1227. X    else
  1228. X        Cfile = "[stdin]";
  1229. X
  1230. X    if (!locname) 
  1231. X        locname = local();
  1232. X    if (*locname == 0) {
  1233. X        locname = "lostinspace";
  1234. X        fprintf(stderr, "%s: using \"%s\" for local name\n",
  1235. X                Argv[0], locname);
  1236. X    }
  1237. X
  1238. X    Home = addnode(locname);    /* add home node */
  1239. X    Home->n_cost = 0;        /* doesn't cost to get here */
  1240. X
  1241. X    yyparse();            /* read in link info */
  1242. X
  1243. X    if (Vflag > 1)
  1244. X        hashanalyze();
  1245. X    vprintf(stderr, "%d vertices, %d edges\n", Ncount, Lcount);
  1246. X    vprintf(stderr, "allocation is %ldk after parsing\n", allocation());
  1247. X
  1248. X    Cfile = "[backlinks]";    /* for tracing back links */
  1249. X    Lineno = 0;
  1250. X
  1251. X    /* compute shortest path tree */
  1252. X    mapit();
  1253. X    vprintf(stderr, "allocation is %ldk after mapping\n", allocation());
  1254. X
  1255. X    /* traverse tree and print paths */
  1256. X    printit();
  1257. X    vprintf(stderr, "allocation is %ldk after printing\n", allocation());
  1258. X
  1259. X    wasted();    /* how much was wasted in memory allocation? */
  1260. X
  1261. X    return 0;
  1262. X}
  1263. X
  1264. Xvoid
  1265. Xdie(s)
  1266. X    char *s;
  1267. X{
  1268. X    fprintf(stderr, "%s: %s; notify the authorities\n", Argv[0], s);
  1269. X#ifdef DEBUG
  1270. X        fflush(stdout);
  1271. X        fflush(stderr);
  1272. X        abort();
  1273. X#else
  1274. X        exit(-1);
  1275. X#endif
  1276. X}
  1277. END_OF_main.c
  1278. if test 3978 -ne `wc -c <main.c`; then
  1279.     echo shar: \"main.c\" unpacked with wrong size!
  1280. fi
  1281. # end of overwriting check
  1282. fi
  1283. if test -f make.honey -a "${1}" != "-c" ; then 
  1284.   echo shar: Will not over-write existing file \"make.honey\"
  1285. else
  1286. echo shar: Extracting \"make.honey\" \(2912 characters\)
  1287. sed "s/^X//" >make.honey <<'END_OF_make.honey'
  1288. X#!/bin/make -f
  1289. X# pathalias -- by steve bellovin, as told to peter honeyman
  1290. X
  1291. X### configuration section
  1292. X###
  1293. X# if you can't or don't intend to use dbm files,
  1294. X# don't bother with DBM or makedb
  1295. XDBM = -ldbm
  1296. X# or if you roll your own ...
  1297. X# DBM = dbm.o
  1298. X###
  1299. X# where is getopt (if not in the c library)?
  1300. X# GETOPT = -lgetopt
  1301. X### end of configuration section 
  1302. X
  1303. XCC = cc -g
  1304. XCFLAGS =  -DSTATIC=extern -DDEBUG
  1305. XLDFLAGS =
  1306. XYFLAGS = -d
  1307. X
  1308. XOBJ = addlink.o addnode.o local.o main.o mapit.o mapaux.o mem.o parse.o printit.o
  1309. XOFILES = addlink.O addnode.O local.O main.O mapit.O mapaux.O mem.O parse.O printit.O
  1310. XHDRS = def.h config.h
  1311. XCSRC = addlink.c addnode.c local.c main.c mapit.c mapaux.c mem.c printit.c
  1312. XLSRC = $(CSRC) parse.c
  1313. XSRC = $(CSRC) parse.y makedb.c arpatxt.c
  1314. X
  1315. Xpathalias: $(OBJ)
  1316. X    $(CC) $(OBJ) $(LDFLAGS) -o pathalias
  1317. X
  1318. Xall: pathalias makedb arpatxt
  1319. X
  1320. X$(OBJ):    $(HDRS)
  1321. X
  1322. Xparse.c: parse.y $(HDRS)
  1323. X    $(YACC) $(YFLAGS) parse.y
  1324. X    sed '/^# line/d' y.tab.c > parse.c
  1325. X
  1326. Xmakedb: makedb.o
  1327. X    $(CC) makedb.o $(LDFLAGS) $(DBM) -o makedb
  1328. X
  1329. Xmakedb.o: config.h
  1330. X
  1331. Xarpatxt: arpatxt.o
  1332. X    $(CC) arpatxt.o $(LDFLAGS) -o arpatxt
  1333. X
  1334. Xclean:
  1335. X    rm -f *.o y.tab.? parse.c
  1336. X
  1337. Xtags: $(SRC) $(HDRS)
  1338. X    ctags -w $(SRC) $(HDRS)
  1339. X
  1340. Xbundle: README CHANGES pathalias.1 Makefile ${HDRS} ${SRC} arpa-privates make.honey
  1341. X    @bundle README CHANGES pathalias.1 Makefile ${HDRS} ${SRC} arpa-privates make.honey
  1342. X
  1343. Xbundle1: README CHANGES pathalias.1 Makefile ${HDRS}
  1344. X    @bundle README CHANGES pathalias.1 Makefile ${HDRS}
  1345. X
  1346. Xbundle2: addlink.c addnode.c local.c main.c
  1347. X    @bundle addlink.c addnode.c local.c main.c
  1348. X
  1349. Xbundle3: mapit.c mapaux.c
  1350. X    @bundle mapit.c mapaux.c
  1351. X
  1352. Xbundle4: mem.c printit.c parse.y
  1353. X    @bundle mem.c printit.c parse.y makedb.c
  1354. X
  1355. Xbundle5: makedb.c arpatxt.c arpa-privates make.honey
  1356. X    @bundle  makedb.c arpatxt.c arpa-privates make.honey
  1357. X
  1358. Xmake.honey: makefile
  1359. X    @cp makefile make.honey
  1360. X
  1361. Xlint:    $(LSRC)
  1362. X    lint -hbau $(CFLAGS) $(LSRC)
  1363. X    lint makedb.c
  1364. X
  1365. X
  1366. X# the remainder is site specific.
  1367. X
  1368. XPATHFILES = paths/* pp/* pm/*
  1369. X
  1370. Xpaths/internet: hosts.txt arpa-privates local.hosts
  1371. X    arpatxt -fi -g citi -g umix -p arpa-privates local.hosts hosts.txt > paths/internet
  1372. X
  1373. XAVOID =
  1374. X
  1375. X# map output (input, really) to lower case; verbose; terminal domains
  1376. XARGS = -viD
  1377. X
  1378. XPARGS=$(ARGS) $(AVOID) $(PATHFILES)
  1379. Xdwon:    paths/local paths/internet
  1380. X    pathalias -l dwon $(PARGS) 2>ERRORS | sort -o dwon
  1381. X
  1382. X# desperation debugging -- examine the costs.
  1383. Xcosts:
  1384. X    pathalias -icvvD ${PARGS} 2>error.costs | awk '{printf("%s\t%s\t%s\n", $$2, $$1, $$3)}' | sort -o pa.costs 
  1385. X
  1386. X# make one BIG file.  a BIG bad idea.
  1387. Xcat:
  1388. X    for i in $(PATHFILES); do cat $$i; echo 'private {}'; done > CAT
  1389. X
  1390. X# make a pathparse database.  -g is undocumented.
  1391. Xedges:
  1392. X    pathalias -g edges $(PARGS) 2>ERRORS > edges.hosts
  1393. X#    makedb edges pa
  1394. X
  1395. Xumich:
  1396. X    pathalias -l umich $(PARGS) 2>umich.ERRORS | sort > umich
  1397. X
  1398. Xciti:    paths/local paths/internet
  1399. X    pathalias -l citi $(PARGS) 2>citi.ERRORS | sort > citi
  1400. X
  1401. Xumix:
  1402. X    pathalias -l umix $(PARGS) 2>umix.ERRORS | sort > umix
  1403. END_OF_make.honey
  1404. if test 2912 -ne `wc -c <make.honey`; then
  1405.     echo shar: \"make.honey\" unpacked with wrong size!
  1406. fi
  1407. # end of overwriting check
  1408. fi
  1409. if test -f makedb.c -a "${1}" != "-c" ; then 
  1410.   echo shar: Will not over-write existing file \"makedb.c\"
  1411. else
  1412. echo shar: Extracting \"makedb.c\" \(2342 characters\)
  1413. sed "s/^X//" >makedb.c <<'END_OF_makedb.c'
  1414. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  1415. X#ifndef lint
  1416. Xstatic char    *sccsid = "@(#)makedb.c    9.1 87/10/04";
  1417. X#endif /* lint */
  1418. X
  1419. X#include <stdio.h>
  1420. X#include "config.h"
  1421. X
  1422. Xtypedef struct {
  1423. X    char *dptr;
  1424. X    int dsize;
  1425. X} datum;
  1426. X
  1427. Xchar *Ofile = ALIASDB, *ProgName;
  1428. X
  1429. X#define USAGE "%s [-o dbmname] [-a] [file ...]\n"
  1430. X
  1431. Xmain(argc, argv)
  1432. X    char *argv[];
  1433. X{    char *ofptr;
  1434. X    int c, append = 0;
  1435. X    extern int optind;
  1436. X    extern char *optarg;
  1437. X
  1438. X    ProgName = argv[0];
  1439. X    while ((c = getopt(argc, argv, "o:a")) != EOF)
  1440. X        switch(c) {
  1441. X        case 'o':    /* dbm output file */
  1442. X            Ofile = optarg;
  1443. X            break;
  1444. X
  1445. X        case 'a':    /* append mode */
  1446. X            append++;
  1447. X            break;
  1448. X
  1449. X        default:
  1450. X            fprintf(stderr, USAGE, ProgName);
  1451. X            exit(1);
  1452. X            break;
  1453. X        }
  1454. X
  1455. X
  1456. X    if ((ofptr = rindex(Ofile, '/')) != 0)
  1457. X        ofptr++;
  1458. X    else
  1459. X        ofptr = Ofile;
  1460. X    if (strlen(ofptr) > 10) {
  1461. X        ofptr[10] = 0;
  1462. X        fprintf(stderr, "%s: using %s for dbm output\n", ProgName, Ofile);
  1463. X    }
  1464. X
  1465. X    if (append == 0 && dbfile(Ofile) != 0) {
  1466. X        perror_(Ofile);
  1467. X        exit(1);
  1468. X    }
  1469. X
  1470. X    if (dbminit(Ofile) < 0) {
  1471. X        perror_(Ofile);
  1472. X        exit(1);
  1473. X    }
  1474. X
  1475. X    if (optind == argc)
  1476. X        makedb((char *) 0);
  1477. X    else for ( ; optind < argc; optind++)
  1478. X        makedb(argv[optind]);
  1479. X    exit(0);
  1480. X}
  1481. X
  1482. Xdbfile(dbf)
  1483. X    char *dbf;
  1484. X{
  1485. X    return (dbcreat(dbf, "dir") != 0 || dbcreat(dbf, "pag") != 0);
  1486. X}
  1487. X
  1488. Xdbcreat(dbf, suffix)
  1489. X    char *dbf, *suffix;
  1490. X{    char buf[BUFSIZ];
  1491. X    int fd;
  1492. X
  1493. X    (void) sprintf(buf, "%s.%s", dbf, suffix);
  1494. X    if ((fd = creat(buf, 0666)) < 0)
  1495. X        return(-1);
  1496. X    (void) close(fd);
  1497. X    return(0);
  1498. X}
  1499. X
  1500. X
  1501. Xmakedb(ifile)
  1502. X    char *ifile;
  1503. X{    char line[BUFSIZ];
  1504. X    datum key, val;
  1505. X
  1506. X    if (ifile && (freopen(ifile, "r", stdin) == NULL)) {
  1507. X        perror_(ifile);
  1508. X        return;
  1509. X    }
  1510. X
  1511. X    /*
  1512. X     * keys and values are 0 terminated.  this wastes time and (disk) space,
  1513. X     * but does lend simplicity and backwards compatibility.
  1514. X     */
  1515. X    key.dptr = line;
  1516. X    while (fgets(line, sizeof(line), stdin) != NULL) {
  1517. X        char *op, *end;
  1518. X
  1519. X        end = line + strlen(line);
  1520. X        end[-1] = 0;    /* kill newline, stuff null terminator */
  1521. X        op = index(line, '\t');
  1522. X        if (op != 0) {
  1523. X            *op++ = 0;
  1524. X            key.dsize = op - line;        /* 0 terminated */
  1525. X            val.dptr = op;
  1526. X            val.dsize = end - op;        /* 0 terminated */
  1527. X        } else {
  1528. X            key.dsize = end - line;        /* 0 terminated */
  1529. X            val.dptr = "\0";        /* why must i do this? */
  1530. X            val.dsize = 1;
  1531. X        }
  1532. X        if (store(key, val) < 0)
  1533. X            perror_(Ofile);
  1534. X    }
  1535. X}
  1536. X
  1537. Xperror_(str)
  1538. X    char    *str;
  1539. X{
  1540. X    fprintf(stderr, "%s: ", ProgName);
  1541. X    perror(str);
  1542. X}
  1543. END_OF_makedb.c
  1544. if test 2342 -ne `wc -c <makedb.c`; then
  1545.     echo shar: \"makedb.c\" unpacked with wrong size!
  1546. fi
  1547. # end of overwriting check
  1548. fi
  1549. if test -f mapaux.c -a "${1}" != "-c" ; then 
  1550.   echo shar: Will not over-write existing file \"mapaux.c\"
  1551. else
  1552. echo shar: Extracting \"mapaux.c\" \(7110 characters\)
  1553. sed "s/^X//" >mapaux.c <<'END_OF_mapaux.c'
  1554. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  1555. X#ifndef lint
  1556. Xstatic char    *sccsid = "@(#)mapaux.c    9.1 87/10/04";
  1557. X#endif /* lint */
  1558. X
  1559. X#include "def.h"
  1560. X
  1561. X/* imports */
  1562. Xextern long Nheap, Hashpart, Tabsize;
  1563. Xextern node **Table, *Home;
  1564. Xextern char *Graphout, *Linkout, *Netchars, **Argv;
  1565. Xextern void freelink(), die();
  1566. Xextern long pack();
  1567. Xextern link *newlink();
  1568. Xextern node *newnode();
  1569. Xextern char *strsave();
  1570. X
  1571. X/* exports */
  1572. Xlong pack();
  1573. Xvoid resetnodes(), dumpgraph(), showlinks();
  1574. Xint tiebreaker();
  1575. Xnode *ncopy();
  1576. X
  1577. X/* privates */
  1578. Xstatic FILE *Gstream;    /* for dumping graph */
  1579. XSTATIC void dumpnode(), untangle(), dfs();
  1580. XSTATIC int height();
  1581. XSTATIC link *lcopy();
  1582. X
  1583. X
  1584. X/*
  1585. X * slide everything from Table[low] to Table[high]
  1586. X * up toward the high end.  make room!  make room!
  1587. X */
  1588. Xlong
  1589. Xpack(low, high)
  1590. X    long low, high;
  1591. X{    long hole, next;
  1592. X
  1593. X    /* find first "hole " */
  1594. X    for (hole = high; hole >= low && Table[hole] != 0; --hole)
  1595. X        ;
  1596. X
  1597. X    /* repeatedly move next filled entry into last hole */
  1598. X    for (next = hole - 1; next >= low; --next) {
  1599. X        if (Table[next] != 0) {
  1600. X            Table[hole] = Table[next];
  1601. X            Table[hole]->n_tloc = hole;
  1602. X            Table[next] = 0;
  1603. X            while (Table[--hole] != 0)    /* find next hole */
  1604. X                ;
  1605. X        }
  1606. X    }
  1607. X    return hole + 1;
  1608. X}
  1609. X
  1610. Xvoid
  1611. Xresetnodes()
  1612. X{    register long i;
  1613. X    register node *n;
  1614. X
  1615. X    for (i = Hashpart; i < Tabsize; i++)
  1616. X        if ((n = Table[i]) != 0) {
  1617. X            n->n_cost = (Cost) 0;
  1618. X            n->n_flag &= ~(NALIAS|ATSIGN|MAPPED|HASLEFT|HASRIGHT|NTERMINAL);
  1619. X            n->n_copy = n;
  1620. X        }
  1621. X        
  1622. X    Home->n_cost = (Cost) 0;
  1623. X    Home->n_flag &= ~(NALIAS|ATSIGN|MAPPED|HASLEFT|HASRIGHT|NTERMINAL);
  1624. X    Home->n_copy = Home;
  1625. X}
  1626. X
  1627. Xvoid    
  1628. Xdumpgraph()
  1629. X{    register long i;
  1630. X    register node *n;
  1631. X
  1632. X    if ((Gstream = fopen(Graphout, "w")) == NULL) {
  1633. X        fprintf(stderr, "%s: ", Argv[0]);
  1634. X        perror(Graphout);
  1635. X        return;
  1636. X    }
  1637. X
  1638. X    untangle();    /* untangle net cycles for proper output */
  1639. X
  1640. X    for (i = Hashpart; i < Tabsize; i++) {
  1641. X        n = Table[i];
  1642. X        if (n == 0)
  1643. X            continue;    /* impossible, but ... */
  1644. X        /* a minor optimization ... */
  1645. X        if (n->n_link == 0)
  1646. X            continue;
  1647. X        /* pathparse doesn't need these */
  1648. X        if (n->n_flag & NNET)
  1649. X            continue;
  1650. X        dumpnode(n);
  1651. X    }
  1652. X}
  1653. X
  1654. XSTATIC void
  1655. Xdumpnode(from)
  1656. X    register node *from;
  1657. X{    register node *to;
  1658. X    register link *l;
  1659. X    link *lnet = 0, *ll, *lnext;
  1660. X
  1661. X    for (l = from->n_link ; l; l = l->l_next) {
  1662. X        to = l->l_to;
  1663. X        if (from == to)
  1664. X            continue;    /* oops -- it's me! */
  1665. X
  1666. X        if ((to->n_flag & NNET) == 0) {
  1667. X            /* host -> host -- print host>host */
  1668. X            if (l->l_cost == INF)
  1669. X                continue;    /* phoney link */
  1670. X            fputs(from->n_name, Gstream);
  1671. X            putc('>', Gstream);
  1672. X            fputs(to->n_name, Gstream);
  1673. X            putc('\n', Gstream);
  1674. X        } else {
  1675. X            /*
  1676. X             * host -> net -- just cache it for now.
  1677. X             * first check for dups.  (quadratic, but
  1678. X             * n is small here.)
  1679. X             */
  1680. X            while (to->n_root && to != to->n_root)
  1681. X                to = to->n_root;
  1682. X            for (ll = lnet; ll; ll = ll->l_next)
  1683. X                if (strcmp(ll->l_to->n_name, to->n_name) == 0)
  1684. X                    break;
  1685. X            if (ll)
  1686. X                continue;    /* dup */
  1687. X            ll = newlink();
  1688. X            ll->l_next = lnet;
  1689. X            ll->l_to = to;
  1690. X            lnet = ll;
  1691. X        }
  1692. X    }
  1693. X
  1694. X    /* dump nets */
  1695. X    if (lnet) {
  1696. X        /* nets -- print host@\tnet,net, ... */
  1697. X        fputs(from->n_name, Gstream);
  1698. X        putc('@', Gstream);
  1699. X        putc('\t', Gstream);
  1700. X        for (ll = lnet; ll; ll = lnext) {
  1701. X            lnext = ll->l_next;
  1702. X            fputs(ll->l_to->n_name, Gstream);
  1703. X            if (lnext)
  1704. X                fputc(',', Gstream);
  1705. X            freelink(ll);
  1706. X        }
  1707. X        putc('\n', Gstream);
  1708. X    }
  1709. X}
  1710. X
  1711. X/*
  1712. X * remove cycles in net definitions. 
  1713. X *
  1714. X * depth-first search
  1715. X *
  1716. X * for each net, run dfs on its neighbors (nets only).  if we return to
  1717. X * a visited node, that's a net cycle.  mark the cycle with a pointer
  1718. X * in the n_root field (which gets us closer to the root of this
  1719. X * portion of the dfs tree).
  1720. X */
  1721. XSTATIC void
  1722. Xuntangle()
  1723. X{    register long i;
  1724. X    register node *n;
  1725. X
  1726. X    for (i = Hashpart; i < Tabsize; i++) {
  1727. X        n = Table[i];
  1728. X        if (n == 0 || (n->n_flag & NNET) == 0 || n->n_root)
  1729. X            continue;
  1730. X        dfs(n);
  1731. X    }
  1732. X}
  1733. X
  1734. XSTATIC void
  1735. Xdfs(n)
  1736. X    register node *n;
  1737. X{    register link *l;
  1738. X    register node *next;
  1739. X
  1740. X    n->n_flag |= INDFS;
  1741. X    n->n_root = n;
  1742. X    for (l = n->n_link; l; l = l->l_next) {
  1743. X        next = l->l_to;
  1744. X        if ((next->n_flag & NNET) == 0)
  1745. X            continue;
  1746. X        if ((next->n_flag & INDFS) == 0) {
  1747. X            dfs(next);
  1748. X            if (next->n_root != next)
  1749. X                n->n_root = next->n_root;
  1750. X        } else
  1751. X            n->n_root = next->n_root;
  1752. X    }
  1753. X    n->n_flag &= ~INDFS;
  1754. X}
  1755. X
  1756. Xvoid
  1757. Xshowlinks() 
  1758. X{    register link *l;
  1759. X    register node *n;
  1760. X    register long i;
  1761. X    FILE    *estream;
  1762. X
  1763. X    if ((estream = fopen(Linkout, "w")) == 0)
  1764. X        return;
  1765. X
  1766. X    for (i = Hashpart; i < Tabsize; i++) {
  1767. X        n = Table[i];
  1768. X        if (n == 0 || n->n_link == 0)
  1769. X            continue;
  1770. X        for (l = n->n_link; l; l = l->l_next) {
  1771. X            fputs(n->n_name, estream);
  1772. X            putc('\t', estream);
  1773. X            if (NETDIR(l) == LRIGHT)
  1774. X                putc(NETCHAR(l), estream);
  1775. X            fputs(l->l_to->n_name, estream);
  1776. X            if (NETDIR(l) == LLEFT)
  1777. X                putc(NETCHAR(l), estream);
  1778. X            fprintf(estream, "(%d)\n", l->l_cost);
  1779. X        }
  1780. X    }
  1781. X    (void) fclose(estream);
  1782. X}
  1783. X
  1784. X/*
  1785. X * n is node in heap, newp is candidate for new parent.
  1786. X * choose between newp and n->n_parent for parent.
  1787. X * return 0 to use newp, non-zero o.w.
  1788. X */
  1789. X#define NEWP 0
  1790. X#define OLDP 1
  1791. Xint
  1792. Xtiebreaker(n, newp)
  1793. X    node *n;
  1794. X    register node *newp;
  1795. X{    register char *opname, *npname, *name;
  1796. X    register node *oldp;
  1797. X    int metric;
  1798. X
  1799. X    oldp = n->n_parent;
  1800. X
  1801. X    /* given the choice, avoid gatewayed nets */
  1802. X    if (GATEWAYED(newp) && !GATEWAYED(oldp))
  1803. X        return OLDP;
  1804. X    if (!GATEWAYED(newp) && GATEWAYED(oldp))
  1805. X        return NEWP;
  1806. X
  1807. X    /* look at real parents, not nets */
  1808. X    while ((oldp->n_flag & NNET) && oldp->n_parent)
  1809. X        oldp = oldp->n_parent;
  1810. X    while ((newp->n_flag & NNET) && newp->n_parent)
  1811. X        newp = newp->n_parent;
  1812. X
  1813. X    /* use fewer hops, if possible */
  1814. X    metric = height(oldp) - height(newp);
  1815. X    if (metric < 0)
  1816. X        return OLDP;
  1817. X    if (metric > 0)
  1818. X        return NEWP;
  1819. X
  1820. X    /*
  1821. X     * compare names
  1822. X     */
  1823. X    opname = oldp->n_name;
  1824. X    npname = newp->n_name;
  1825. X    name = n->n_name;
  1826. X
  1827. X    /* use longest common prefix with parent */
  1828. X    while (*opname == *name && *npname == *name && *name) {
  1829. X        opname++;
  1830. X        npname++;
  1831. X        name++;
  1832. X    }
  1833. X    if (*opname == *name)
  1834. X        return OLDP;
  1835. X    if (*npname == *name)
  1836. X        return NEWP;
  1837. X
  1838. X    /* use shorter host name */
  1839. X    metric = strlen(opname) - strlen(npname);
  1840. X    if (metric < 0)
  1841. X        return OLDP;
  1842. X    if (metric > 0)
  1843. X        return NEWP;
  1844. X
  1845. X    /* use larger lexicographically */
  1846. X    metric = strcmp(opname, npname);
  1847. X    if (metric < 0)
  1848. X        return NEWP;
  1849. X    return OLDP;
  1850. X}
  1851. X
  1852. XSTATIC int
  1853. Xheight(n)
  1854. X    register node *n;
  1855. X{    register int i = 0;
  1856. X
  1857. X    if (n == 0)
  1858. X        return 0;
  1859. X    while ((n = n->n_parent) != 0)
  1860. X        if (ISADOMAIN(n) || !(n->n_flag & NNET))
  1861. X            i++;
  1862. X    return i;
  1863. X}
  1864. X    
  1865. X/* l is a terminal edge from n -> next; return a copy of next */
  1866. Xnode *
  1867. Xncopy(n)
  1868. X    register node *n;
  1869. X{    register node *ncp;
  1870. X
  1871. X    ncp = newnode();
  1872. X    ncp->n_name = n->n_name;    /* nonvolatile */
  1873. X    ncp->n_tloc = --Hashpart;    /* better not be > 20% of total ... */
  1874. X    if (Hashpart == Nheap)
  1875. X        die("too many terminal links");
  1876. X    Table[Hashpart] = ncp;
  1877. X    ncp->n_copy = n->n_copy;    /* circular list */
  1878. X    n->n_copy = ncp;
  1879. X    ncp->n_link = lcopy(n->n_link);
  1880. X    ncp->n_flag = (n->n_flag & ~(NALIAS|ATSIGN|MAPPED|HASLEFT|HASRIGHT)) | NTERMINAL;
  1881. X    return ncp;
  1882. X}
  1883. X
  1884. XSTATIC link *
  1885. Xlcopy(l)
  1886. X    register link *l;
  1887. X{    register link *lcp;
  1888. X
  1889. X    if (l == 0)
  1890. X        return 0;
  1891. X    lcp = newlink();
  1892. X    *lcp = *l;
  1893. X    lcp->l_flag &= ~LTREE;
  1894. X    lcp->l_next = lcopy(l->l_next);
  1895. X    return lcp;
  1896. X}
  1897. END_OF_mapaux.c
  1898. if test 7110 -ne `wc -c <mapaux.c`; then
  1899.     echo shar: \"mapaux.c\" unpacked with wrong size!
  1900. fi
  1901. # end of overwriting check
  1902. fi
  1903. if test -f mem.c -a "${1}" != "-c" ; then 
  1904.   echo shar: Will not over-write existing file \"mem.c\"
  1905. else
  1906. echo shar: Extracting \"mem.c\" \(4277 characters\)
  1907. sed "s/^X//" >mem.c <<'END_OF_mem.c'
  1908. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  1909. X#ifndef lint
  1910. Xstatic char    *sccsid = "@(#)mem.c    9.1 87/10/04";
  1911. X#endif
  1912. X
  1913. X#include "def.h"
  1914. X
  1915. X/* exports */
  1916. Xextern void freelink(), wasted();
  1917. Xextern long allocation();
  1918. Xlong Ncount;
  1919. X
  1920. X/* imports */
  1921. Xextern char *sbrk();
  1922. Xextern char *Netchars;
  1923. Xextern int Vflag;
  1924. Xextern void die();
  1925. X
  1926. X/* privates */
  1927. XSTATIC void nomem();
  1928. Xstatic link *Lcache;
  1929. Xstatic unsigned int Memwaste;
  1930. X
  1931. Xlink    *
  1932. Xnewlink()
  1933. X{    register link *rval;
  1934. X
  1935. X    if (Lcache) {
  1936. X         rval = Lcache;
  1937. X        Lcache = Lcache->l_next;
  1938. X        strclear((char *) rval, sizeof(link));
  1939. X    } else if ((rval = (link * ) calloc(1, sizeof(link))) == 0)
  1940. X        nomem();
  1941. X    return rval;
  1942. X}
  1943. X
  1944. X/* caution: this destroys the contents of l_next */
  1945. Xvoid
  1946. Xfreelink(l)
  1947. X    link *l;
  1948. X{
  1949. X    l->l_next = Lcache;
  1950. X    Lcache = l;
  1951. X}
  1952. X
  1953. Xnode    *
  1954. Xnewnode()
  1955. X{    register node *rval;
  1956. X
  1957. X    if ((rval = (node * ) calloc(1, sizeof(node))) == 0)
  1958. X        nomem();
  1959. X    Ncount++;
  1960. X    return rval;
  1961. X}
  1962. X
  1963. Xchar    *
  1964. Xstrsave(s)
  1965. X    char *s;
  1966. X{    register char *r;
  1967. X
  1968. X    if ((r = malloc((unsigned) strlen(s) + 1)) == 0)
  1969. X        nomem();
  1970. X    (void) strcpy(r, s);
  1971. X    return r;
  1972. X}
  1973. X
  1974. X#ifndef strclear
  1975. Xvoid
  1976. Xstrclear(str, len)
  1977. X    register char *str;
  1978. X    register long len;
  1979. X{
  1980. X    while (--len >= 0)
  1981. X        *str++ = 0;
  1982. X}
  1983. X#endif /*strclear*/
  1984. X
  1985. Xnode    **
  1986. Xnewtable(size)
  1987. X    long size;
  1988. X{    register node **rval;
  1989. X
  1990. X    if ((rval = (node **) calloc(1, (unsigned int) size * sizeof(node *))) == 0) 
  1991. X        nomem();
  1992. X    return rval;
  1993. X}
  1994. X
  1995. Xfreetable(t, size)
  1996. X    node **t;
  1997. X    long size;
  1998. X{
  1999. X#ifdef MYMALLOC
  2000. X    addtoheap((char *) t, size * sizeof(node *));
  2001. X#else
  2002. X    free((char *) t);
  2003. X#endif
  2004. X}
  2005. X
  2006. XSTATIC void
  2007. Xnomem()
  2008. X{
  2009. X    static char epitaph[128];
  2010. X
  2011. X    sprintf(epitaph, "out of memory (%ldk allocated)", allocation());
  2012. X    die(epitaph);
  2013. X}
  2014. X
  2015. X/* data space allocation -- main sets `dataspace' very early */
  2016. Xlong
  2017. Xallocation()
  2018. X{
  2019. X    static char *dataspace;
  2020. X    long rval;
  2021. X
  2022. X    if (dataspace == 0) {        /* first time */
  2023. X        dataspace = sbrk(0);    /* &end? */
  2024. X        return 0;
  2025. X    }
  2026. X    rval = (sbrk(0) - dataspace)/1024;
  2027. X    if (rval < 0)            /* funny architecture? */
  2028. X        rval = -rval;
  2029. X    return rval;
  2030. X}
  2031. X
  2032. X/* how much memory has been wasted? */
  2033. Xvoid
  2034. Xwasted()
  2035. X{
  2036. X    if (Memwaste == 0)
  2037. X        return;
  2038. X    vprintf(stderr, "memory allocator wasted %ld bytes\n", Memwaste);
  2039. X}
  2040. X
  2041. X#ifdef MYMALLOC
  2042. X
  2043. X/* use c library malloc/calloc here, and here only */
  2044. X#undef malloc
  2045. X#undef calloc
  2046. Xextern char *malloc(), *calloc();
  2047. X
  2048. X/* allocate in MBUFSIZ chunks.  4k works ok (less 16 for malloc quirks). */
  2049. X#define MBUFSIZ (4 * 1024 - 16)
  2050. X
  2051. X/* 
  2052. X * mess with ALIGN at your peril.  longword (== 0 mod 4)
  2053. X * alignment seems to work everywhere.
  2054. X */
  2055. X
  2056. X#define ALIGN 2
  2057. X
  2058. Xtypedef struct heap heap;
  2059. Xstruct heap {
  2060. X    heap *h_next;
  2061. X    long h_size;
  2062. X};
  2063. X
  2064. Xstatic heap *Mheap;    /* not to be confused with a priority queue */
  2065. X
  2066. Xaddtoheap(p, size)
  2067. X    char *p;
  2068. X    long size;
  2069. X{    int adjustment;
  2070. X    heap *pheap;
  2071. X
  2072. X    /* p is aligned, but it doesn't hurt to check */
  2073. X    adjustment = align(p);
  2074. X    p += adjustment;
  2075. X    size -= adjustment;
  2076. X
  2077. X    if (size < 1024)
  2078. X        return;        /* can't happen */
  2079. X    pheap = (heap *) p;    /* pheap is shorthand */
  2080. X    pheap->h_next = Mheap;
  2081. X    pheap->h_size = size;
  2082. X    Mheap = pheap;
  2083. X}
  2084. X
  2085. X/*
  2086. X * buffered malloc()
  2087. X *    returns space initialized to 0.  calloc isn't used, since
  2088. X *    strclear can be faster.
  2089. X *
  2090. X * free is ignored, except for very large objects,
  2091. X * which are returned to the heap with addtoheap(). 
  2092. X */
  2093. X
  2094. Xchar    *
  2095. Xmymalloc(n)
  2096. X    register unsigned int n;
  2097. X{    static unsigned int size; /* how much do we have on hand? */
  2098. X    static char *mstash;      /* where is it? */
  2099. X    register char *rval;
  2100. X
  2101. X    if (n >= 1024) {        /* for hash table */
  2102. X        rval = malloc(n);    /* aligned */
  2103. X        if (rval)
  2104. X            strclear(rval, n);
  2105. X        return rval;
  2106. X    }
  2107. X
  2108. X    n += align((char *) n);    /* keep everything aligned */
  2109. X
  2110. X    if (n > size) {
  2111. X        Memwaste += size;    /* toss the fragment */
  2112. X        /* look in the heap */
  2113. X        if (Mheap) {
  2114. X            mstash = (char *) Mheap;    /* aligned */
  2115. X            size = Mheap->h_size;
  2116. X            Mheap = Mheap->h_next;
  2117. X        } else {
  2118. X            mstash = malloc(MBUFSIZ);    /* aligned */
  2119. X            if (mstash == 0) {
  2120. X                size = 0;
  2121. X                return 0;
  2122. X            }
  2123. X            size = MBUFSIZ;
  2124. X        }
  2125. X        strclear(mstash, size);        /* what if size > 2^16? */
  2126. X    }
  2127. X    rval = mstash;
  2128. X    mstash += n;
  2129. X    size -= n;
  2130. X    return rval;
  2131. X}
  2132. X
  2133. X/*
  2134. X * what's the (mis-)alignment of n?  return the complement of
  2135. X * n mod 2^ALIGN
  2136. X */
  2137. Xalign(n)
  2138. X    char *n;
  2139. X{    register int abits;    /* misalignment bits in n */
  2140. X
  2141. X    abits = (int) n & ~(0xff << ALIGN) & 0xff;
  2142. X    if (abits == 0)
  2143. X        return 0;
  2144. X    return (1 << ALIGN) - abits;
  2145. X}
  2146. X
  2147. X#endif /*MYMALLOC*/
  2148. END_OF_mem.c
  2149. if test 4277 -ne `wc -c <mem.c`; then
  2150.     echo shar: \"mem.c\" unpacked with wrong size!
  2151. fi
  2152. # end of overwriting check
  2153. fi
  2154. if test -f printit.c -a "${1}" != "-c" ; then 
  2155.   echo shar: Will not over-write existing file \"printit.c\"
  2156. else
  2157. echo shar: Extracting \"printit.c\" \(6855 characters\)
  2158. sed "s/^X//" >printit.c <<'END_OF_printit.c'
  2159. X/* pathalias -- by steve bellovin, as told to peter honeyman */
  2160. X#ifndef lint
  2161. Xstatic char    *sccsid = "@(#)printit.c    9.1 87/10/04";
  2162. X#endif
  2163. X
  2164. X#include "def.h"
  2165. X
  2166. X/*
  2167. X * print the routes by traversing the shortest path tree in preorder.
  2168. X * use lots of char bufs -- profiling indicates this costs about 5 kbytes
  2169. X */
  2170. X
  2171. X/* exports */
  2172. Xextern void printit();
  2173. X
  2174. X/* imports */
  2175. Xextern int Cflag, Vflag, Dflag, Fflag;
  2176. Xextern node *Home;
  2177. Xextern char *Netchars;
  2178. Xextern void die();
  2179. X
  2180. X/* privates */
  2181. Xstatic link *Ancestor;    /* for -f option */
  2182. XSTATIC void preorder(), setpath(), printhost(), printdomain();
  2183. XSTATIC char *hostpath();
  2184. X
  2185. X/* in practice, even the longest paths are < 100 bytes */
  2186. X#define PATHSIZE 512
  2187. X
  2188. Xvoid
  2189. Xprintit()
  2190. X{    link *l;
  2191. X    char pbuf[PATHSIZE];
  2192. X
  2193. X    /* print home */
  2194. X    if (Cflag)
  2195. X        printf("%ld\t", (long) Home->n_cost);
  2196. X    printf("%s\t%%s\n", Home->n_name);
  2197. X    
  2198. X    strcpy(pbuf, "%s");
  2199. X    for (l = Home->n_link; l; l = l->l_next) {
  2200. X        if (l->l_flag & LTREE) {
  2201. X            l->l_flag &= ~LTREE;
  2202. X            Ancestor = l;
  2203. X            preorder(l, pbuf);
  2204. X            strcpy(pbuf, "%s");
  2205. X        }
  2206. X    }
  2207. X    fflush(stdout);
  2208. X    fflush(stderr);
  2209. X}
  2210. X
  2211. X/*
  2212. X * preorder traversal of shortest path tree.
  2213. X */
  2214. XSTATIC void
  2215. Xpreorder(l, ppath)
  2216. X    register link *l;
  2217. X    char *ppath;
  2218. X{    register node *n;
  2219. X    node *ncp;        /* circular copy list */
  2220. X    Cost cost;
  2221. X    char npath[PATHSIZE];
  2222. X    short p_dir;        /* DIR bits of parent (for nets) */
  2223. X    char p_op;        /* net op of parent (for nets) */
  2224. X
  2225. X    setpath(l, ppath, npath);
  2226. X    n = l->l_to;
  2227. X    if (printable(n)) {
  2228. X        if (Fflag)
  2229. X            cost = Ancestor->l_to->n_cost;
  2230. X        else
  2231. X            cost = n->n_cost;
  2232. X        if (ISADOMAIN(n))
  2233. X            printdomain(n, npath, cost);
  2234. X        else if (!(n->n_flag & NNET)) {
  2235. X            printhost(n, npath, cost);
  2236. X        }
  2237. X        n->n_flag |= PRINTED;
  2238. X        for (ncp = n->n_copy; ncp != n; ncp = ncp->n_copy)
  2239. X            ncp->n_flag |= PRINTED;
  2240. X    }
  2241. X
  2242. X    /* prepare routing bits for domain members */
  2243. X    p_dir = l->l_flag & LDIR;
  2244. X    p_op = l->l_netop;
  2245. X
  2246. X    /* recursion */
  2247. X    for (l = n->n_link; l; l = l->l_next) {
  2248. X        if (!(l->l_flag & LTREE))
  2249. X            continue;
  2250. X        /* network member inherits the routing syntax of its gateway */
  2251. X        if (ISANET(n)) {
  2252. X            l->l_flag = (l->l_flag & ~LDIR) | p_dir;
  2253. X            l->l_netop = p_op;
  2254. X        }
  2255. X        l->l_flag &= ~LTREE;
  2256. X        preorder(l, npath);
  2257. X    }
  2258. X}
  2259. X
  2260. XSTATIC int
  2261. Xprintable(n)
  2262. X    register node *n;
  2263. X{    node *ncp;
  2264. X    link *l;
  2265. X
  2266. X    if (n->n_flag & PRINTED)
  2267. X        return 0;
  2268. X
  2269. X    /* is there a cheaper copy? */
  2270. X    for (ncp = n->n_copy; n != ncp; ncp = ncp->n_copy) {
  2271. X        if (!(ncp->n_flag & MAPPED))
  2272. X            continue;    /* unmapped copy */
  2273. X
  2274. X        if (n->n_cost > ncp->n_cost)
  2275. X            return 0;    /* cheaper copy */
  2276. X
  2277. X        if (n->n_cost == ncp->n_cost && !(ncp->n_flag & NTERMINAL))
  2278. X            return 0;    /* synthetic copy */
  2279. X    }
  2280. X
  2281. X    /* will a domain route suffice? */
  2282. X    if (Dflag && !ISANET(n) && ISADOMAIN(n->n_parent)) {
  2283. X        /*
  2284. X         * are there any interesting links?  a link
  2285. X         * is interesting if it doesn't point back
  2286. X         * to the parent, and is not an alias.
  2287. X         */
  2288. X
  2289. X        /* check n */
  2290. X        for (l = n->n_link; l; l = l->l_next) {
  2291. X            if (l->l_to == n->n_parent)
  2292. X                continue;
  2293. X            if ((!l->l_flag & LALIAS))
  2294. X                return 1;
  2295. X        }
  2296. X
  2297. X        /* check copies of n */
  2298. X        for (ncp = n->n_copy; ncp != n; ncp = ncp->n_copy) {
  2299. X            for (l = ncp->n_link; l; l = l->l_next) {
  2300. X                if (l->l_to == n->n_parent)
  2301. X                    continue;
  2302. X                if (!(l->l_flag & LALIAS))
  2303. X                    return 1;
  2304. X            }
  2305. X        }
  2306. X
  2307. X        /* domain route suffices */
  2308. X        return 0;
  2309. X    }
  2310. X    return 1;
  2311. X}
  2312. X
  2313. XSTATIC void
  2314. Xsetpath(l, ppath, npath) 
  2315. X    link *l;
  2316. X    register char *ppath, *npath;
  2317. X{    register node *next, *parent;
  2318. X    char netchar;
  2319. X
  2320. X    next = l->l_to;
  2321. X    parent = next->n_parent;
  2322. X    netchar = NETCHAR(l);
  2323. X
  2324. X    /* for magic @->% conversion */
  2325. X    if (parent->n_flag & ATSIGN)
  2326. X        next->n_flag |= ATSIGN;
  2327. X
  2328. X    /*
  2329. X     * i've noticed that distant gateways to domains frequently get
  2330. X     * ...!gateway!user@dom.ain wrong.  ...!gateway!user%dom.ain
  2331. X     * seems to work, so if next is a domain and the parent is
  2332. X     * not the local host, force a magic %->@ conversion.  in this
  2333. X     * context, "parent" is the nearest ancestor that is not a net.
  2334. X     */
  2335. X    while (ISANET(parent))
  2336. X        parent = parent->n_parent;
  2337. X    if (ISADOMAIN(next) && parent != Home)
  2338. X        next->n_flag |= ATSIGN;
  2339. X
  2340. X    /*
  2341. X     * special handling for nets (including domains) and aliases.
  2342. X     * part of the trick is to treat aliases to domains as 0 cost
  2343. X     * links.  (the author believes they should be declared as such
  2344. X     * in the input, but the world disagrees).
  2345. X     */
  2346. X    if (ISANET(next) || ((l->l_flag & LALIAS) && !ISADOMAIN(parent))) {
  2347. X        strcpy(npath, ppath);
  2348. X        return;
  2349. X    }
  2350. X        
  2351. X    if (netchar == '@')
  2352. X        if (next->n_flag & ATSIGN)
  2353. X            netchar = '%';    /* shazam?  shaman? */
  2354. X        else
  2355. X            next->n_flag |= ATSIGN;
  2356. X
  2357. X    /* remainder should be a sprintf -- foo on '%' as an operator */
  2358. X    for ( ; *npath = *ppath; ppath++) {
  2359. X        if (*ppath == '%') {
  2360. X            switch(ppath[1]) {
  2361. X            case 's':
  2362. X                ppath++;
  2363. X                npath = hostpath(npath, l, netchar);
  2364. X                break;
  2365. X
  2366. X            case '%':
  2367. X                *++npath = *++ppath;
  2368. X                npath++;
  2369. X                break;
  2370. X
  2371. X            default:
  2372. X                die("unknown escape in setpath");
  2373. X                break;
  2374. X            }
  2375. X        } else
  2376. X            npath++;
  2377. X    }
  2378. X}
  2379. X
  2380. XSTATIC char *
  2381. Xhostpath(path, l, netchar)
  2382. X    register char *path;
  2383. X    register link *l;
  2384. X    char netchar;
  2385. X{    register node *prev;
  2386. X
  2387. X    prev = l->l_to->n_parent;
  2388. X    if (NETDIR(l) == LLEFT) {
  2389. X        /* host!%s */
  2390. X        strcpy(path, l->l_to->n_name);
  2391. X        path += strlen(path);
  2392. X        while (ISADOMAIN(prev)) {
  2393. X            strcpy(path, prev->n_name);
  2394. X            path += strlen(path);
  2395. X            prev = prev->n_parent;
  2396. X        }
  2397. X        *path++ = netchar;
  2398. X        if (netchar == '%')
  2399. X            *path++ = '%';
  2400. X        *path++ = '%';
  2401. X        *path++ = 's';
  2402. X    } else {
  2403. X        /* %s@host */
  2404. X        *path++ = '%';
  2405. X        *path++ = 's';
  2406. X        *path++ = netchar;
  2407. X        if (netchar == '%')
  2408. X            *path++ = '%';
  2409. X        strcpy(path, l->l_to->n_name);
  2410. X        path += strlen(path);
  2411. X        while (ISADOMAIN(prev)) {
  2412. X            strcpy(path, prev->n_name);
  2413. X            path += strlen(path);
  2414. X            prev = prev->n_parent;
  2415. X        }
  2416. X    }
  2417. X    return path;
  2418. X}
  2419. X
  2420. XSTATIC void
  2421. Xprinthost(n, path, cost)
  2422. X    register node *n;
  2423. X    char *path;
  2424. X    Cost cost;
  2425. X{
  2426. X    if (n->n_flag & PRINTED)
  2427. X        die("printhost called twice");
  2428. X    n->n_flag |= PRINTED;
  2429. X    /* skip private hosts */
  2430. X    if ((n->n_flag & ISPRIVATE) == 0) {
  2431. X        if (Cflag)
  2432. X            printf("%ld\t", (long) cost);
  2433. X        fputs(n->n_name, stdout);
  2434. X        putchar('\t');
  2435. X        puts(path);
  2436. X    }
  2437. X}
  2438. X
  2439. XSTATIC void
  2440. Xprintdomain(n, path, cost)
  2441. X    register node *n;
  2442. X    char *path;
  2443. X    Cost cost;
  2444. X{    node *p;
  2445. X
  2446. X    if (n->n_flag & PRINTED)
  2447. X        die("printdomain called twice");
  2448. X    n->n_flag |= PRINTED;
  2449. X
  2450. X    /*
  2451. X     * print a route for dom.ain if it is a top-level domain, unless
  2452. X     * it is private.
  2453. X     *
  2454. X     * print a route for sub.dom.ain only if all its ancestor dom.ains
  2455. X     * are private and sub.dom.ain is not private.
  2456. X     */
  2457. X    if (!ISADOMAIN(n->n_parent)) {
  2458. X        /* top-level domain */
  2459. X        if (n->n_flag & ISPRIVATE) {
  2460. X            vprintf(stderr, "ignoring private top-level domain %s\n", n->n_name);
  2461. X            return;
  2462. X        }
  2463. X    } else {
  2464. X        /* subdomain */
  2465. X        for (p = n->n_parent; ISADOMAIN(p); p = p->n_parent)
  2466. X            if (!(p->n_flag & ISPRIVATE))
  2467. X                return;
  2468. X        if (n->n_flag & ISPRIVATE)
  2469. X            return;
  2470. X    }
  2471. X
  2472. X    /* print it (at last!) */
  2473. X    if (Cflag)
  2474. X        printf("%ld\t", (long) cost);
  2475. X    do {
  2476. X        fputs(n->n_name, stdout);
  2477. X        n = n->n_parent;
  2478. X    } while (ISADOMAIN(n));
  2479. X    putchar('\t');
  2480. X    puts(path);
  2481. X}
  2482. END_OF_printit.c
  2483. if test 6855 -ne `wc -c <printit.c`; then
  2484.     echo shar: \"printit.c\" unpacked with wrong size!
  2485. fi
  2486. # end of overwriting check
  2487. fi
  2488. echo shar: End of archive 1 \(of 2\).
  2489. cp /dev/null ark1isdone
  2490. MISSING=""
  2491. for I in 1 2 ; do
  2492.     if test ! -f ark${I}isdone ; then
  2493.     MISSING="${MISSING} ${I}"
  2494.     fi
  2495. done
  2496. if test "${MISSING}" = "" ; then
  2497.     echo You have unpacked both archives.
  2498.     rm -f ark[1-9]isdone
  2499. else
  2500.     echo You still need to unpack the following archives:
  2501.     echo "        " ${MISSING}
  2502. fi
  2503. ##  End of shell archive.
  2504. exit 0
  2505.